iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 7
0
自我挑戰組

Pro Design Patterns in Swift5系列 第 7

Day7: Prototype 模式(上)

  • 分享至 

  • xImage
  •  

https://ithelp.ithome.com.tw/upload/images/20200922/20130138vFx1PMt1VX.jpg

Photo by Gunnar Ridderström on Unsplash


// 程式列 5-1

class Sum {
    var resultsCache: [[Int]];
    var firstValue: Int;
    var secondValue: Int;
    
    init(first:Int, second: Int) {
// OLD: resultsCache = [[Int]](count: 10, repeatedValue: [Int](count: 10, repeatedValue: 0));
        resultsCache = [[Int]](repeating: ([Int](repeating: 0, count: 10)), count: 10);
        for i in 0..<10 {
            for j in 0..<10 {
                resultsCache[i][j] = i + j;
            }
        }
        
        self.firstValue = first;
        self.secondValue = second;
    }
    
    var Result: Int {
        get {
            return firstValue < resultsCache.count
                && secondValue < resultsCache[firstValue].count
            ? resultsCache[firstValue][secondValue]
                : firstValue + secondValue;
        }
    }
}

var calc1 = Sum(first: 0, second: 9).Result;
var calc2 = Sum(first: 3, second: 8).Result;

print("Calc1: \(calc1) Calc2 \(calc2)");
(count: Int, repeatedValue: Element) 更新為 (repeating: Element, count: Int)

Reference


// 程式列 5-2

class Sum {
    var resultsCache: [[Int]];
    var firstValue: Int;
    var secondValue: Int;
    
    init(first:Int, second: Int, cacheSize: Int) {
//        resultsCache = [[Int]](count: 10, repeatedValue: [Int](count: 10, repeatedValue: 0));
        resultsCache = [[Int]](repeating: ([Int](repeating: 0, count: cacheSize)), count: cacheSize);
        for i in 0..<cacheSize {
            for j in 0..<cacheSize {
                resultsCache[i][j] = i + j;
            }
        }
        
        self.firstValue = first;
        self.secondValue = second;
    }
    
    var Result: Int {
        get {
            return firstValue < resultsCache.count
                && secondValue < resultsCache[firstValue].count
            ? resultsCache[firstValue][secondValue]
                : firstValue + secondValue;
        }
    }
}

var calc1 = Sum(first: 0, second: 9, cacheSize: 100).Result;
var calc2 = Sum(first: 3, second: 8, cacheSize: 20).Result;

print("Calc1: \(calc1) Calc2 \(calc2)")

struct 值型別

// 程式列 5-3

struct Appointment {
    var name: String;
    var day: String;
    var place: String;
    
    func printDetail(label: String) {
        print("\(label) with \(name) on \(day) at \(place)");
    }
}

var beerMeeting = Appointment(name: "Bob", day: "Mon", place: "Joe's Bar")

var workMeeting = beerMeeting;
workMeeting.name = "Alice";
workMeeting.day = "Fri";
workMeeting.place = "Conference Rm 2";

beerMeeting.printDetail(label: "Social");
workMeeting.printDetail(label: "Work");

class 參考型別

// 程式列 5-4

class Appointment {
    var name: String;
    var day: String;
    var place: String;
    
    init(name: String, day: String, place: String) {
        self.name = name;
        self.day = day;
        self.place = place;
    }

    func printDetail(label: String) {
        print("\(label) with \(name) on \(day) at \(place)");
    }
}

var beerMeeting = Appointment(name: "Bob", day: "Mon", place: "Joe's Bar")

var workMeeting = beerMeeting;
workMeeting.name = "Alice";
workMeeting.day = "Fri";
workMeeting.place = "Conference Rm 2";

beerMeeting.printDetail(label: "Social");
workMeeting.printDetail(label: "Work");

一句話的定義struct與class差異: 影分身之術就是class參考型別, 穢土轉生之術就是struct值型別。
第二句話的補充:影分身之術鳴人主體物件被培因黑棒插中, 其他分身物件都受到影響。而穢土轉生之術召喚互不影響的物件。


// 程式列 5-5

class Appointment: NSObject, NSCoding {
    var name: String;
    var day: String;
    var place: String;
    
    init(name: String, day: String, place: String) {
        self.name = name;
        self.day = day;
        self.place = place;
    }

    required init(coder aDecoder: NSCoder) {
        name = aDecoder.decodeObject(forKey: "name") as? String ?? ""
        day = aDecoder.decodeObject(forKey: "day") as? String ?? ""
        place = aDecoder.decodeObject(forKey: "place") as? String ?? ""
    }

    func encode(with aCoder: NSCoder) {
        aCoder.encode(name, forKey: "name")
        aCoder.encode(day, forKey: "day")
        aCoder.encode(place, forKey: "place")
    }

    func printDetail(label: String) {
        print("\(label) with \(name) on \(day) at \(place)");
    }
    
    func copyWithZone(zone: NSZone) -> AnyObject {
        return Appointment(name: self.name, day: self.day, place: self.place)
    }
}

var beerMeeting = Appointment(name: "Bob", day: "Mon", place: "Joe's Bar")

var workMeeting = beerMeeting.copy() as! Appointment;
workMeeting.name = "Alice";
workMeeting.day = "Fri";
workMeeting.place = "Conference Rm 2";

beerMeeting.printDetail(label: "Social");
workMeeting.printDetail(label: "Work");

Reference


// 程式列 5-6 pass
// 程式列 5-7

class Location: NSObject, NSCopying {
    var name: String;
    var address: String;
    
    init(name: String, address: String) {
        self.name = name;
        self.address = address;
    }
    
    required init(coder aDecoder: NSCoder) {
        name = aDecoder.decodeObject(forKey: "name") as? String ?? ""
        address = aDecoder.decodeObject(forKey: "address") as? String ?? ""
    }

    func encode(with aCoder: NSCoder) {
        aCoder.encode(name, forKey: "name")
        aCoder.encode(address, forKey: "address")
    }
    
    func copy(with zone: NSZone? = nil) -> Any {
        let copy =  Location(name: name, address: address)
        return copy;
    }
}

class Appointment: NSObject, NSCoding {
    var name: String;
    var day: String;
    var place: Location;
    
    init(name: String, day: String, place: Location) {
        self.name = name;
        self.day = day;
        self.place = place;
    }

    required init(coder aDecoder: NSCoder) {
        name = aDecoder.decodeObject(forKey: "name") as? String ?? ""
        day = aDecoder.decodeObject(forKey: "day") as? String ?? ""
        place = aDecoder.decodeObject(forKey: "place") as? Location ?? Location(name: "",address: "");
    }

    func encode(with aCoder: NSCoder) {
        aCoder.encode(name, forKey: "name")
        aCoder.encode(day, forKey: "day")
        aCoder.encode(place, forKey: "place")
    }

    func printDetail(label: String) {
        print("\(label) with \(name) on \(day) at \(place)");
    }
    
    func copy(with zone: NSZone? = nil) -> Any {
        return Appointment(name: name, day: day, place: (place.copy() as! Location));
    }
}

var beerMeeting = Appointment(name: "Bob", day: "Mon", place: Location(name: "Joe's Bar", address: "123 Main St"))

//FIXME:
var workMeeting = beerMeeting.copy() as! Appointment;
workMeeting.name = "Alice";
workMeeting.day = "Fri";
workMeeting.place.name = "Conference Rm 2";
workMeeting.place.address = "Company HQ";

beerMeeting.printDetail(label: "Social");
workMeeting.printDetail(label: "Work");


查克拉耗盡, 先喝杯水
謝謝閱讀


上一篇
Day6: Chapter4: Object Template 模式(下)
下一篇
Day8: Prototype 模式(下)
系列文
Pro Design Patterns in Swift517
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言